/*
 * Copyright (c) 2013-2015 Charkey. All rights reserved.
 *
 * This software is the confidential and proprietary information of Charkey.
 * You shall not disclose such Confidential Information and shall use it only
 * in accordance with the terms of the agreements you entered into with Charkey.
 *
 * Charkey MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
 *
 * Charkey SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
 * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 */

package cn.simastudio.talos.core.controller;

import cn.simastudio.talos.common.constants.ApiStatusCode;
import cn.simastudio.talos.common.model.JsonResult;
import cn.simastudio.talos.common.utils.ExceptionUtils;
import cn.simastudio.talos.common.utils.spring.SpringUtils;
import cn.simastudio.talos.core.model.base.ScheduleJob;
import cn.simastudio.talos.core.service.base.impl.ScheduleJobService;
import org.apache.commons.lang3.StringUtils;
import org.quartz.CronScheduleBuilder;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.List;

/**
 * Usage: 任务执行
 *
 * @author Charkey
 * @date 2015/5/23 22:12
 */
@Controller
@RequestMapping("/task")
public class ScheduleJobController {

    private static final Logger LOGGER = LoggerFactory.getLogger(ScheduleJobController.class);

    @Autowired
    private ScheduleJobService scheduleJobService;

    @RequestMapping("/taskList")
    public String taskList(Model model) {
        List<ScheduleJob> taskList = scheduleJobService.getAllTask();
        model.addAttribute("taskList", taskList);
        return "/jsp/task/taskList.jsp";
    }

    @RequestMapping("/add")
    @ResponseBody
    public JsonResult taskList(HttpServletRequest request, ScheduleJob scheduleJob) {
        JsonResult result = new JsonResult();
        try {
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
        } catch (Exception e) {
            result.setCode(ApiStatusCode.INVALID_PARAMETER);
            result.setMessage("cron表达式有误，不能被解析！");
            return result;
        }
        Object obj = null;
        try {
            if (StringUtils.isNotBlank(scheduleJob.getBeanName())) {
                obj = SpringUtils.getBean(scheduleJob.getBeanName());
            } else {
                Class clazz = Class.forName(scheduleJob.getBeanClass());
                obj = clazz.newInstance();
            }
        } catch (Exception e) {
            // do nothing.........
        }
        if (obj == null) {
            result.setCode(ApiStatusCode.INVALID_PARAMETER);
            result.setMessage("未找到目标类！");
            return result;
        } else {
            Class clazz = obj.getClass();
            Method method = null;
            try {
                method = clazz.getMethod(scheduleJob.getMethodName(), null);
            } catch (Exception e) {
                result.setCode(ApiStatusCode.GENERAL_EXCEPTION);
                result.setMessage(ExceptionUtils.getExceptionMessage(e));
            }
            if (method == null) {
                result.setCode(ApiStatusCode.INVALID_PARAMETER);
                result.setMessage("未找到目标方法！");
                return result;
            }
        }
        try {
            scheduleJobService.addTask(scheduleJob);
        } catch (Exception e) {
            result.setCode(ApiStatusCode.INVALID_PARAMETER);
            result.setMessage("保存失败，检查 name group 组合是否有重复！");
            return result;
        }
        result.setCode(ApiStatusCode.ACCEPTED);
        result.setMessage("保存成功！");
        return result;
    }

    @RequestMapping("/changeJobStatus")
    @ResponseBody
    public JsonResult changeJobStatus(Integer id, String cmd) {
        JsonResult result = new JsonResult();
        try {
            scheduleJobService.changeStatus(id, cmd);
        } catch (SchedulerException e) {
            if (LOGGER.isErrorEnabled()) {
                LOGGER.error("Error occurred when change job status, {}", e);
            }
            result.setCode(ApiStatusCode.GENERAL_EXCEPTION);
            result.setMessage(ExceptionUtils.getExceptionMessage(e));
            return result;
        }
        result.setCode(ApiStatusCode.ACCEPTED);
        result.setMessage("修改成功");
        return result;
    }

    @RequestMapping("/updateCron")
    @ResponseBody
    public JsonResult updateCron(Integer id, String cron) {
        JsonResult result = new JsonResult();
        try {
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
        } catch (Exception e) {
            result.setCode(ApiStatusCode.GENERAL_EXCEPTION);
            result.setMessage(ExceptionUtils.getExceptionMessage(e));
            return result;
        }
        try {
            scheduleJobService.updateCron(id, cron);
        } catch (SchedulerException e) {
            result.setCode(ApiStatusCode.GENERAL_EXCEPTION);
            result.setMessage("cron更新失败！");
            return result;
        }
        result.setCode(ApiStatusCode.ACCEPTED);
        result.setMessage("Cron表达式更新成功");
        return result;
    }
}
